Popular Searches
Popular Course Categories
Popular Courses

State and Component Re-rendering

State and Component Re-rendering

State Management with useState

State and Component Re-rendering in React JS

State and Component Re-rendering are important concepts in React JS. State stores information that can change over time, while re-rendering is the process in which React calls a component again to determine what the user interface should display. When state changes, React can re-render the component and update the necessary parts of the interface.

Learn more: JustAcademy React JS Training Course | Register for React JS Course Demo


1. What Is State in React?

State is data that a React component remembers between renders. It allows a component to display changing information based on user actions, application events, or other updates.

Examples of state include:

  • A counter value that increases or decreases.
  • A username entered into a form.
  • A dropdown menu's open or closed status.
  • A list of products in a shopping cart.
  • A selected tab in a navigation menu.
  • Whether a user is logged in or logged out.

Example

import { useState } from 'react';
function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>
        Increase
      </button>
    </div>
  );
}
export default Counter;

Explanation: The state variable count starts at 0. When the user clicks the button, setCount() requests a state update. React renders the component again and displays the new count.


2. What Is Component Rendering?

Rendering in React means calling a component function to calculate what should appear in the user interface. React uses the component's current props, state, and context to determine the JSX it returns.

For example:

function Welcome() {
  return <h1>Welcome to React JS!</h1>;
}
export default Welcome;

When React renders this component, it evaluates the function and determines that a heading should appear on the screen.

Important Points

  • Rendering calculates the component's output.
  • Rendering can happen more than once during a component's lifetime.
  • A render does not necessarily mean the browser DOM will change.
  • React compares the new output with the previous output and applies necessary DOM changes during the commit phase.

3. What Is Component Re-rendering?

Component re-rendering means React calls a component again after its initial render to calculate the latest user interface.

A re-render may happen when:

  • The component's state is updated.
  • The component receives new props from its parent.
  • A context value used by the component changes.
  • The parent component re-renders, causing its child components to be rendered again under the normal rendering behavior.

Example: State-Based Re-rendering

import { useState } from 'react';
function Message() {
  const [message, setMessage] = useState('Hello');
  return (
    <div>
      <p>{message}</p>
      <button onClick={() => setMessage('Welcome!')}>
        Change Message
      </button>
    </div>
  );
}
export default Message;

How it works:

  1. The component initially renders with the message Hello.
  2. The user clicks the Change Message button.
  3. setMessage('Welcome!') requests a state update.
  4. React renders the component again using the new state.
  5. The displayed message changes to Welcome!

4. Relationship Between State and Re-rendering

State and re-rendering work together to keep the user interface synchronized with the component's data.

User performs an action
          ↓
Event handler executes
          ↓
State setter is called
          ↓
React schedules a render
          ↓
Component function runs again
          ↓
React compares the new output
          ↓
Necessary DOM changes are committed
          ↓
Browser displays the updated interface

For example, when a user clicks an Add to Cart button, React can update the cart quantity in state and render the new quantity on the screen.


5. When Does React Re-render a Component?

5.1 When State Changes

Calling a state setter can schedule a re-render.

const [count, setCount] = useState(0);
function handleClick() {
  setCount(count + 1);
}

When the state changes from 0 to 1, React renders the component again with the updated value.

5.2 When Props Change

Props are values passed from a parent component to a child component. When a parent supplies new props, React normally renders the child again.

function Greeting({ name }) {
  return <h2>Hello, {name}!</h2>;
}
function App() {
  const [name, setName] = useState('Amit');
  return (
    <div>
      <Greeting name={name} />
      <button onClick={() => setName('Priya')}>
        Change Name
      </button>
    </div>
  );
}

When the parent's name state changes, it passes the updated name to Greeting, and the child renders with the new prop.

5.3 When Context Changes

A component that reads a context value can re-render when that context value changes.

Context is useful for sharing information such as a theme, language preference, or authenticated user across multiple components without passing props through every intermediate component.

5.4 When the Parent Re-renders

By default, when a parent component re-renders, React also renders its child components as it processes the updated component tree. This can happen even when a child's props appear unchanged. Memoization can sometimes skip a child render when its props have not changed.


6. Using the useState() Hook to Trigger Re-rendering

The useState() Hook lets functional components store state and request updates.

Syntax

const [state, setState] = useState(initialValue);
Part Description
useState() React Hook used to declare state.
state The current state value for the render.
setState The function used to request a state update.
initialValue The starting state value used during initialization.

Example

import { useState } from 'react';
function Toggle() {
  const [isVisible, setIsVisible] = useState(false);
  return (
    <div>
      <button onClick={() => setIsVisible(!isVisible)}>
        Toggle
      </button>
      {isVisible && <p>This message is visible.</p>}
    </div>
  );
}
export default Toggle;

When the user clicks the button, the Boolean state changes. React re-renders the component and conditionally displays or hides the message.


7. Does Every State Update Cause a Visible DOM Change?

No. A state update can cause React to render a component without requiring a visible DOM change.

React compares the output of the new render with the previous output. If the rendered result is the same, React may not need to modify the DOM.

Example

import { useState } from 'react';
function Example() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(0)}>
        Set Count to Zero
      </button>
    </div>
  );
}
export default Example;

If count is already 0, calling setCount(0) supplies the same primitive value. React can skip rendering work for that state update. React's internal scheduling and development behavior can affect exactly when component functions are called, so avoid relying on render counts for application logic.


8. State Updates Are Not Immediately Reflected in the Current Render

Calling a state setter does not change the state variable in the currently executing render. The next value becomes available when React renders the component again.

Example

import { useState } from 'react';
function Counter() {
  const [count, setCount] = useState(0);
  function handleClick() {
    setCount(count + 1);
    console.log(count);
  }
  return (
    <button onClick={handleClick}>
      Count: {count}
    </button>
  );
}
export default Counter;

When the button is clicked for the first time, the console can display 0 even though React subsequently renders the button with Count: 1. The event handler reads the state value from the render in which that handler was created.

Using a Functional Updater

setCount(previousCount => previousCount + 1);

This approach calculates the next value from the pending previous state and is especially useful when multiple updates are queued.


9. React's Three-Step Update Process

React updates the user interface through three main steps.

Step 1: Trigger

A render is triggered by the initial display or by an update such as a state change. New props or context values can also lead to rendering.

Step 2: Render

React calls the component functions to calculate the latest JSX output. Rendering should be a pure calculation: it should not directly change external data or perform side effects.

Step 3: Commit

React applies the necessary changes to the DOM. If the new output does not require a DOM change, React may leave the DOM unchanged.

Trigger → Render → Commit

This process helps React update the interface efficiently instead of rebuilding every DOM element for every render.


10. Re-rendering Parent and Child Components

React applications are usually built as component trees. A state update in a parent component can cause the parent and its descendants to render again as React processes the tree.

Example

import { useState } from 'react';
function Child({ message }) {
  console.log('Child rendered');
  return <p>{message}</p>;
}
function Parent() {
  const [count, setCount] = useState(0);
  console.log('Parent rendered');
  return (
    <div>
      <p>Count: {count}</p>
      <Child message="Hello from Child" />
      <button onClick={() => setCount(count + 1)}>
        Increase
      </button>
    </div>
  );
}
export default Parent;

When the count changes, the parent re-renders. Under normal rendering behavior, React also renders the child while processing the updated tree, even though the child's message prop remains the same.

Note: Console logs are useful for learning, but render counts can vary because React may batch work, skip unnecessary work, or perform additional development checks.


11. Preventing Unnecessary Re-rendering with React.memo()

React.memo() is a performance optimization that can allow React to skip rendering a function component when its props have not changed according to a shallow comparison. It does not prevent the component from re-rendering when its own state or a context it uses changes.

Example

import { memo, useState } from 'react';
const Greeting = memo(function Greeting({ name }) {
  console.log('Greeting rendered');
  return <h3>Hello, {name}!</h3>;
});
function App() {
  const [name, setName] = useState('Amit');
  const [count, setCount] = useState(0);
  return (
    <div>
      <Greeting name={name} />
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increase Count
      </button>
      <button onClick={() => setName('Priya')}>
        Change Name
      </button>
    </div>
  );
}
export default App;

Explanation:

  • Changing the count updates the parent component.
  • The memoized Greeting component can skip rendering if its name prop remains unchanged.
  • Changing the name causes Greeting to render with the new prop.

Use memoization when there is a meaningful performance benefit. It is not necessary for every component.


12. Difference Between Rendering and Re-rendering

Rendering Re-rendering
Includes the initial calculation of a component's output. Refers to subsequent calculations of the component's output.
Occurs when the component first appears. Can occur after state, props, or context changes, or when its parent renders.
React determines the initial UI. React calculates the latest UI and compares it with the previous output.
Initial DOM elements may be created and committed. Only necessary DOM changes are committed.

13. Common Causes of Unnecessary Re-rendering

  • Updating state even when the value does not need to change.
  • Keeping too much state in a high-level parent component.
  • Creating new object or array props on every render when stable references would be useful for memoized children.
  • Passing new callback functions to memoized children when stable callbacks would provide a measurable benefit.
  • Using context for frequently changing values across a very large component tree without considering component boundaries.
  • Adding state for values that can be calculated directly from existing props or state.

Not all re-renders are bad. React is designed to render components efficiently. Optimize only when there is a real performance problem or a clear benefit.


14. Best Practices for State and Re-rendering

  • Use useState() for data that affects what the component displays.
  • Update state through the setter function instead of mutating it directly.
  • Use functional updates when the next state depends on the previous state.
  • Keep rendering logic pure and avoid side effects during rendering.
  • Keep state close to the components that need it when possible.
  • Do not assume that a state setter immediately changes the current state variable.
  • Remember that React can batch multiple state updates.
  • Use React.memo(), useMemo(), or useCallback() only when they help with a specific performance need.
  • Do not rely on a particular number of component function calls.
  • Use React Developer Tools Profiler to investigate performance issues.

15. Practical Example: Live Character Counter

This example demonstrates how updating state causes a component to render the latest input and character count.

import { useState } from 'react';
function CharacterCounter() {
  const [text, setText] = useState('');
  return (
    <div>
      <h2>Character Counter</h2>
      <textarea
        value={text}
        onChange={event => setText(event.target.value)}
        placeholder="Type something..."
      />
      <p>Characters: {text.length}</p>
      <p>Your text: {text}</p>
      <button onClick={() => setText('')}>
        Clear
      </button>
    </div>
  );
}
export default CharacterCounter;

How It Works

  1. The text state starts as an empty string.
  2. The user types into the textarea.
  3. The onChange handler updates the state.
  4. React renders the component with the new text.
  5. The character count and displayed text update automatically.
  6. Clicking Clear sets the state to an empty string, causing the interface to display the cleared value.

16. Interview Questions and Answers

Q1. What is component re-rendering in React?

Component re-rendering means React calls a component again to calculate the latest UI output.

Q2. What are common reasons for re-rendering?

Common reasons include a state update, new props, a changed context value, or a parent component rendering again.

Q3. Does every re-render update the DOM?

No. React compares the new output with the previous output and commits only necessary DOM changes.

Q4. How does useState() affect re-rendering?

Calling its setter requests a state update. React then schedules rendering work when appropriate.

Q5. Does setState change the current variable immediately?

No. The state variable in the currently executing render retains its existing value. The next value is available in a subsequent render.

Q6. What is React.memo()?

React.memo() is an optimization that can skip rendering a function component when its props have not changed under a shallow comparison.

Q7. Can a child component re-render when its props have not changed?

Yes. For example, a parent re-render normally causes React to render its child components too, unless React can skip that work through an optimization or other rendering behavior.

Q8. What is the difference between render and commit?

Render calculates what the UI should look like. Commit applies the necessary changes to the DOM.

Q9. Why should rendering be pure?

Pure rendering makes the UI predictable and allows React to render, pause, retry, or discard render work safely.

Q10. Should developers prevent all re-renders?

No. Re-rendering is a normal part of React. Developers should focus on measuring and addressing unnecessary work rather than trying to prevent every render.


17. Practice Exercises

  1. Create a counter that displays the updated count after each button click.
  2. Create a toggle button that shows or hides a message.
  3. Build a form that displays a live preview of the entered username.
  4. Create a parent component that passes a changing name prop to a child component.
  5. Use console.log() to observe parent and child rendering during practice.
  6. Use React.memo() to optimize a child component whose props remain unchanged.
  7. Build a character counter that updates while the user types.
  8. Use React Developer Tools Profiler to investigate which components render during an interaction.

18. Quick Revision Checklist

  • Understand state and component rendering.
  • Know how state updates can trigger re-rendering.
  • Understand how props and context changes can affect rendering.
  • Distinguish rendering from DOM updates.
  • Know the Trigger, Render, and Commit steps.
  • Understand why state setters do not immediately change the current render's value.
  • Know the purpose and limitations of React.memo().
  • Keep render logic pure and avoid unnecessary optimization.
  • Practice state-driven UI updates with counters, forms, and toggles.

19. Useful Resources


20. Conclusion

State and component re-rendering are fundamental concepts in React JS. State stores changing information, and state updates can cause React to render a component again. React then compares the latest output with the previous output and commits the necessary DOM changes. By understanding this process, writing pure rendering logic, updating state correctly, and optimizing only when needed, developers can create interactive and efficient React applications.

To learn more, visit JustAcademy React JS Training Course or register for a React JS course demo.

whatsapp